﻿using System.Collections.Generic;
using System.Linq;

using CommonBehaviors.Actions;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.Pathing;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

#if USE_DUNGEONBUDDY_DLL
using Bots.DungeonBuddyDll.Attributes;
using Bots.DungeonBuddyDll.Helpers;
namespace Bots.DungeonBuddyDll.Dungeon_Scripts.Classic
#else
using Bots.DungeonBuddy.Attributes;
    using Bots.DungeonBuddy.Helpers;
    using Bots.DungeonBuddy.Profiles;
namespace Bots.DungeonBuddy.Dungeon_Scripts.Classic
#endif
{
    public class WailingCaverns : Dungeon
    {
        #region Overrides of Dungeon

        public override uint DungeonId
        {
            get { return 1; }
        }

        public override WoWPoint Entrance
        {
            get
            {
                return new WoWPoint(-743.4651f, -2215.294f, 15.46369f);
            }
        }

        private const uint Kresh = 3653;
        const uint NightmareEctoplasm = 5763;
        public override void IncludeTargetsFilter(List<WoWObject> incomingunits, HashSet<WoWObject> outgoingunits)
        {
            base.IncludeTargetsFilter(incomingunits, outgoingunits);

            foreach (WoWUnit unit in incomingunits.Select(obj => obj.ToUnit()))
            {
                if (!StyxWoW.Me.Combat && StyxWoW.Me.IsTank())
                {
                    //Force add bugged mobs to pull, such as the goblin and a few defies that return !IsHostile
                    if (unit.Entry == Kresh && (StyxWoW.Me.Location.PathDistance(unit.Location) < 40f))
                        outgoingunits.Add(unit);

                    if (unit.Entry == NightmareEctoplasm && BossManager.CurrentBoss != null && BossManager.CurrentBoss.Name == "Mutanus the Devourer")
                        outgoingunits.Add(unit);

                }
            }
        }


        public override void WeighTargetsFilter(List<Targeting.TargetPriority> units)
        {
            foreach (Targeting.TargetPriority t in units)
            {
                WoWObject prioObject = t.Object;

                //We kill his adds first
                if (prioObject.Entry == 3840 || prioObject.Entry == 5756)
                {
                    t.Score += 400;
                }
            }
        }

        #endregion

        public bool EventStarted;


        [EncounterHandler(0)]
        public Composite RootLogic()
        {
            return
                new PrioritySelector(
                    ScriptHelpers.CreateJumpDown(
                        nat =>
                        !ScriptHelpers.IsBossAlive("Lord Cobrahn") &&
                        StyxWoW.Me.Location.Distance(new WoWPoint(-104.6688, 426.2907, -74.10992)) < 30,
                        (new WoWPoint(-104.6688, 426.2907, -74.10992)), (new WoWPoint(-91.53806, 420.0687, -106.4197))),
                    ScriptHelpers.CreateJumpDown(
                        nat =>
                        !ScriptHelpers.IsBossAlive("Skum") &&
                        StyxWoW.Me.Location.Distance(new WoWPoint(-291.5874, -5.171218, -58.48951)) < 30,
                        (new WoWPoint(-291.5874, -5.171218, -58.48951)), (new WoWPoint(-284.1962, 3.52924, -63.7272))),
                    ScriptHelpers.CreateJumpDown(
                        nat =>
                        !ScriptHelpers.IsBossAlive("Verdan the Everliving") &&
                        StyxWoW.Me.Location.Distance(new WoWPoint(-55.53799, 46.36995, -29.13713)) < 50,
                        (new WoWPoint(-55.53799, 46.36995, -29.13713)), (new WoWPoint(-45.38879, 47.57143, -107.9036)))

                   // ScriptHelpers.CreateJumpDown(
                  //      nat =>
                   //     //!ScriptHelpers.IsBossAlive("Verdan the Everliving") &&
                   //     StyxWoW.Me.Location.Distance(new WoWPoint(-273.067f, 32.96025f, -58.79515f)) < 10,
                    //    (new WoWPoint(-273.067f, 32.96025f, -58.79515f)), (new WoWPoint(-273.6475f, 31.54448f, -59.07084f)))
                    );
        }

        [EncounterHandler(3671, "Lady Anacondra")]
        public Composite LadyAnacondraFight()
        {
            return
                new PrioritySelector();
        }

        [EncounterHandler(3653, "Kresh")]
        public Composite KreshFight()
        {
            return
                new PrioritySelector();
        }

        [EncounterHandler(3670, "Lord Pythas")]
        public Composite LordPythasFight()
        {
            return
                new PrioritySelector();
        }

        [EncounterHandler(3669, "Lord Cobrahn")]
        public Composite LordCobrahnFight()
        {
            return
                new PrioritySelector();
        }

        [EncounterHandler(3674, "Skum")]
        public Composite SkumFight()
        {
            return
                new PrioritySelector();
        }

        [EncounterHandler(3673, "Lord Serpentis")]
        public Composite LordSerpentisFight()
        {
            return
                new PrioritySelector();
        }

        [EncounterHandler(5775, "Verdan the Everliving")]
        public Composite VerdantheEverlivingFight()
        {
            return
                new PrioritySelector();
        }

        private WoWUnit EventNPC { get { return ObjectManager.GetObjectsOfType<WoWUnit>().FirstOrDefault(x => x.Entry == 3678); } }


        [EncounterHandler(3654, "Mutanus the Devourer", Mode = CallBehaviorMode.CurrentBoss)]
        public Composite MutanustheDevourerFight()
        {
            WoWUnit boss = null;
            WoWUnit muyoh = null;
            const int muyohId = 3678;
            var muyohStartLoc = new WoWPoint(-134.965, 125.402, -78.17783);
            var muyohEndLoc = new WoWPoint(114.9415, 237.7185, -96.02783);

            return new PrioritySelector(ctx => boss = ctx as WoWUnit,
                new Decorator(ctx => boss == null,
                    new PrioritySelector( ctx => muyoh = ObjectManager.GetObjectsOfType<WoWUnit>().FirstOrDefault(u => u.Entry == muyohId),
                    
                        new Decorator(ctx => muyoh == null && StyxWoW.Me.Location.DistanceSqr(muyohStartLoc) <= 60*60,
                            ScriptHelpers.CreateMoveToContinue(ctx => true,() => muyohEndLoc,false)),

                         ScriptHelpers.CreateTankTalkToThenEscortNpc(muyohId, muyohStartLoc, muyohEndLoc))));
        }

        private readonly WoWPoint _poolLoc = new WoWPoint(-41.61144, 43.14034, -107.488);
        private readonly WoWPoint _poolExitLoc = new WoWPoint(-62.00883f, 59.99511f, -106.1908f);

        public override MoveResult MoveTo(WoWPoint location)
        {
            if (StyxWoW.Me.IsSwimming && StyxWoW.Me.Location.DistanceSqr(_poolLoc) <= 30 * 30)
            {
                Navigator.PlayerMover.MoveTowards(_poolExitLoc);
                return MoveResult.Moved;
            }
            return base.MoveTo(location);
        }
    }
}